/*
 * estructuras.h
 *
 *  Created on: 25/09/2011
 *      Author: utn_so
 */

typedef struct
{
  int8_t BS_jmpBoot [3];
  int8_t BS_OEMName [8];
  int16_t BPB_BytsPerSec;
  int8_t BPB_SecPerClus;
  int16_t BPB_RsvdSecCnt;
  int8_t BPB_NumFATs;
  int16_t BPB_RootEntCnt;
  int16_t BPB_TotSec16;
  int8_t BPB_Media;
  int16_t BPB_FATSz16;
  int16_t BPB_SecPerTrk;
  int16_t BPB_NumHeads;
  int32_t BPB_HiddSec;
  int32_t BPB_TotSec32;
  int32_t BPB_FATSz32; /* Cantidad De Sectores que ocupa una Fat */
  int16_t BPB_ExtFlags;
  int16_t BPB_FSVer;
  int32_t BPB_RootClus; /* Número del primer Cluster del Directorio Raiz*/
  int16_t BPB_FSInfo;
  int16_t BPB_BkBootSec;
  int8_t BPB_Reserved [12];
  int8_t BS_DrvNum;
  int8_t BS_Reserved1;
  int8_t BS_BootSig;
  int32_t BS_VolID;
  int8_t BS_VolLab [11];
  int8_t BS_FilSysType [8];
  int8_t BS_BootCode [420];
  int16_t BS_BootSign;
}__attribute__ ((__packed__)) stBootSector;

typedef struct
{
  int8_t FSI_Firma [4];
  int8_t FSI_Reserved [480];
  int8_t FSI_Firma2 [4];
  int32_t FSI_FreeClusters;
  int32_t FSI_MostRecClust;
  int8_t FSI_Reserved2 [12];
  int8_t FSI_Firma3 [4];
}__attribute__ ((__packed__)) stFSInfo;

typedef struct
{
  uint8_t LFN_secuenceNumber;
  uint16_t LFN_NombreParte1 [5];
  int8_t LFN_Atributos;
  int8_t LFN_Reservados;
  int8_t LFN_CheckDOS;
  uint16_t LFN_NombreParte2 [6];
  int16_t LFN_PrimerCluster;
  uint16_t LFN_NombreParte3 [2];
}__attribute__ ((__packed__)) stLongFileName;

typedef struct
{
  uint8_t DT_FileName [8]; /*El Byte Inicial es el que determina si esta disponible o no */
  uint8_t DT_Extension [3];
  uint8_t DT_FileAtrib; /* 0x0F es para determinar una entrada de nombre largo */
  int8_t DT_Reserved;
  int8_t DT_CreateTimeFR; /*En milisegundos de 0 a 199 */
  int16_t DT_CreateTime; /* Little Endian 15-11 Horas, 10-5 Minutos, 4-0 Segundos --> Para los segundos hay q usar el anterior tambien */
  int16_t DT_CreateDate; /* Idem Anterior: 15-9 Año ; 8-5 Mes ; 4-0 Dia */
  int16_t DT_UltimaFechaAcc;
  uint16_t DT_ClusterInicialHigh; /*High 2 bytes of first cluster Number (?) */
  int16_t DT_LastModTime;
  int16_t DT_LastModDate;
  uint16_t DT_ClusterInicialLow; /* Low 2 bytes of first cluster */
  uint32_t DT_FileSize; /*Directorios o SubDirectorios deberian tener 0 */
}__attribute__ ((__packed__)) stDirectoryTable;

typedef struct
{
  char DTCN_FileName [14];
  stDirectoryTable EntradaDirectorio;
}__attribute__ ((__packed__)) stDirectoryConNombreLargo;

typedef struct
{
  int32_t nroConexion;
  pthread_mutex_t mutex;
}__attribute__ ((__packed__)) stPoolMutex;
typedef struct
{
  stPoolMutex *poolConexiones;
  pthread_mutex_t mutexPool;
}__attribute__ ((__packed__)) stPoolConMutex;

typedef struct
{
  uint32_t *fatRegion;
  pthread_mutex_t bloqueaFat;
}__attribute__ ((__packed__)) stFatConMutex;
typedef struct
{
  char *pDirIp;
  int16_t puerto;
  int16_t cantidadConexiones;
  int16_t tamanioBloque;
  int16_t tamCache;
  int16_t tiempoEsperaFat;
}__attribute__ ((__packed__)) t_config;

/*Estructura Para Almacenar los archivos Abiertos. El Cluster Inicial,tamaño,cantidad de aperturas y la cache */
typedef struct
{
  int32_t nroCluster;
  time_t ultimoAcceso;
  char *cluster;
  int8_t modificado; // Byte Para Saber Si tengo que escribirlo en disco o No
}__attribute__ ((__packed__)) stCache;

typedef struct
{
  char *nombre;
  uint32_t clusterInicial;
  uint32_t cantidadAperturas;
  uint32_t tamArchivo;
  stCache *dataCache;
  pthread_mutex_t mutexNodo;
}__attribute__ ((__packed__)) stArchivosAbiertos;

/* Lista Archivos Abiertos (Necesaria Para Cache) */
struct nodoArchivo
{
  stArchivosAbiertos datos;
  struct nodoArchivo *next;
};
typedef struct nodoArchivo t_nodoArchivos;
typedef struct
{
  pthread_mutex_t lista;
  t_nodoArchivos *cabeza;
  t_nodoArchivos *cola;
}__attribute__ ((__packed__)) t_listaArchivos;

/* Bit Vector Para Buscar Cluster Libre de la FAT, Son 2 BITS, el primero, libre o ocupado, el 2do dirty o clean. */
typedef struct {
  uint8_t ocupado : 1;
  uint8_t clean : 1 ;
  pthread_mutex_t bloqueastBits;
} stBits;
